package com.example.interceptor.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @Description 自定义切面
 * @Author lihw
 * @Date 2023/12/6 13:20
 */
@Aspect
@Component
public class CustomAspect {

    /**
     *  @annotation 用于匹配当前执行方法持有指定注解的方法
     *  @within 用于匹配所有持有指定注解类型内的所有方法
     */
    @Pointcut("@annotation(com.example.interceptor.aop.annotation.LhwAop) || @within(com.example.interceptor.aop.annotation.LhwAop)")
    public void init() {
    }


    @Before("init()")
    public void before() {
        System.out.println("执行before");
    }

    @After("init()")
    public void after() {
        System.out.println("执行after");
    }

    // 下面的方法 和上面 after的写法都可以
    // @After("@annotation(com.demo.sb_component.component.aop.annotation.LhwAop) || @within(com.demo.sb_component.component.aop.annotation.LhwAop)")
    // public void after() {
    //     System.out.println("执行after");
    // }

    @Around("init()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("around before");
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("around after");
        if (proceed instanceof String) {
            proceed = "change:" + proceed;
        }
        return proceed;
    }


    @AfterReturning(returning = "ret", pointcut = "init()")
    public void afterReturning(JoinPoint joinPoint, Object ret) {
        if (!Objects.isNull(ret)) {
            System.out.println("返回结果为: " + ret.toString());
        }

    }

    @AfterThrowing(pointcut = "init()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println("afterThrowing");
        e.printStackTrace();
    }

}
